package mips.instructions.cop0;

import mips.instructions.Instruction;

/**
 * <code>MTC0</code> instruction<br/>
 * Move To Coprocessor<br/>
 * @author jnmartin84@gmail.com
 */
public class MTC0 extends Instruction {

	private static final String INSTRUCTION_NAME = "MTC0";
	private static final MTC0 INSTANCE = new MTC0();

	private MTC0(){}

	public static MTC0 getInstance() {
		return INSTANCE;
	}

	/**
	 * <b>Format:</b><br/>
	 * MTCz rt, rd<br/><br/>
	 * <b>Description:</b><br/>
	 * The contents of general register rt are loaded into coprocessor register rd<br/>
	 * of coprocessor z.<br/><br/>
	 * <b>Operation:</b><br/>
	 * T: data &larr; GPR[rt]<br/>
	 * T+1: CPR[z,rd] &larr; data
	 */
	@Override
	public final void execute(final int instruction) {

		mips.instructions.Instruction.RT = (instruction >> 16) & 0x0000001F;
		mips.instructions.Instruction.RD = (instruction >> 11) & 0x0000001F;

		mips.COP0.CONTROL[RD] = mips.R4300i.GPR[RT];

		mips.R4300i.PC = mips.R4300i.nPC;
		mips.R4300i.nPC = mips.R4300i.PC + 4;
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String emit(final int instruction) {
		
		mips.instructions.Instruction.RT = (instruction >> 16) & 0x0000001F;
		mips.instructions.Instruction.RD = (instruction >> 11) & 0x0000001F;
		
		return	"		mips.COP0.CONTROL["+mips.instructions.Instruction.RD+"] = mips.R4300i.GPR["+mips.instructions.Instruction.RT+"];\n" + 
				"		\n" + 
				"		mips.R4300i.PC = mips.R4300i.nPC;\n" + 
				"		mips.R4300i.nPC = mips.R4300i.PC + 4;\n";
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName(final int instruction) {
		return getName();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName() {
		return INSTRUCTION_NAME;
	}
}